package in.hooray.ws;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WsClient {
	
	private Class<?> serviceClass;

	private String address;

	private String methodName;

	private Class<?>[] parameterTypes;

	private Object[] parameter;

	/**
	 * @return
	 */
	public Object invoke() {
		if (address == null || "".equals(address.trim())) {
			LOGGER.info("ws的目标地址不能为空");
			return null;
		}
		if (methodName == null || "".equals(methodName.trim())) {
			LOGGER.info("方法名称不能为空");
			return null;
		}
		if (parameterTypes != null && parameter != null
				&& parameterTypes.length != parameter.length) {
			LOGGER.info("参数类型个数和参数个数不匹配");
			return null;
		}
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		//factory.getHandlers().add(new JitecAuthHandler());
		factory.getOutInterceptors().add(new LoggingOutInterceptor());
		if (factory.getProperties() == null) {
			Map<String, Object> properties = new HashMap<String, Object>();
			factory.setProperties(properties);
		}
		factory.getProperties().put("set-jaxb-validation-event-handler", "false");
		factory.setServiceClass(serviceClass);
		factory.setAddress(address);
		try {
			Object obj = factory.create();
			if (obj != null) {
				Method method = serviceClass.getDeclaredMethod(methodName,
						parameterTypes);
				Object result = method.invoke(obj, parameter);
				return result;
			}
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.info(e.getMessage());
		}
		return null;
	} 
	
	private final static Logger LOGGER = LoggerFactory
			.getLogger(WsClient.class);

	/**
	 * <p>
	 * <strong>Description:</strong> 无参数方法时
	 * </p>
	 * 
	 * @param clazz
	 * @param address
	 * @param methodName
	 * @return
	 * @author <a href="mailto: duanxuhua@163.com">段绪华</a>
	 * @update 日期: 2014年3月14日 <a href="mailto: xxx@xx.xx">作者中文名</a> 变更描述
	 */
	public static Object invoke(Class<?> clazz, String address,
			String methodName) {
		return invoke(clazz, address, methodName, null, null);
	}

	/**
	 * <p>
	 * <strong>Description:</strong> 有参数方法时
	 * </p>
	 * 
	 * @param clazz
	 * @param address
	 * @param methodName
	 * @param parameterTypes
	 * @param parameter
	 * @return
	 * @author <a href="mailto: duanxuhua@163.com">段绪华</a>
	 * @update 日期: 2014年3月14日 <a href="mailto: xxx@xx.xx">作者中文名</a> 变更描述
	 */
	public static Object invoke(Class<?> clazz, String address,
			String methodName, Class<?>[] parameterTypes, Object[] parameter) {
		if (address == null || "".equals(address.trim())) {
			LOGGER.info("ws的目标地址不能为空");
			return null;
		}
		if (methodName == null || "".equals(methodName.trim())) {
			LOGGER.info("方法名称不能为空");
			return null;
		}
		if (parameterTypes != null && parameter != null
				&& parameterTypes.length != parameter.length) {
			LOGGER.info("参数类型个数和参数个数不匹配");
			return null;
		}
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		//factory.getHandlers().add(new JitecAuthHandler());
		factory.getOutInterceptors().add(new LoggingOutInterceptor());
		if (factory.getProperties() == null) {
			Map<String, Object> properties = new HashMap<String, Object>();
			factory.setProperties(properties);
		}
		factory.getProperties().put("set-jaxb-validation-event-handler",
				"false");
		factory.setServiceClass(clazz);
		factory.setAddress(address);
		try {
			Object obj = factory.create();
			if (obj != null) {
				Method method = clazz.getDeclaredMethod(methodName,
						parameterTypes);
				Object result = method.invoke(obj, parameter);
				return result;
			}
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.info(e.getMessage());
		}
		return null;
	}

	public Class<?> getServiceClass() {
		return serviceClass;
	}

	public void setServiceClass(Class<?> serviceClass) {
		this.serviceClass = serviceClass;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getMethodName() {
		return methodName;
	}

	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

	public Class<?>[] getParameterTypes() {
		return parameterTypes;
	}

	public void setParameterTypes(Class<?>[] parameterTypes) {
		this.parameterTypes = parameterTypes;
	}

	public Object[] getParameter() {
		return parameter;
	}

	public void setParameter(Object[] parameter) {
		this.parameter = parameter;
	}
}
